"""
统一核心模块 - 整合配置管理、日志系统、事件总线等核心功能
"""

import os
import json
import yaml
import logging
import logging.handlers
from typing import Dict, Any, Optional, Callable, List
from datetime import datetime
from pathlib import Path
from dataclasses import dataclass
from enum import Enum
import asyncio
from collections import defaultdict


class LogLevel(Enum):
    """日志级别"""
    DEBUG = "DEBUG"
    INFO = "INFO"
    WARNING = "WARNING"
    ERROR = "ERROR"
    CRITICAL = "CRITICAL"


class EventTypes(Enum):
    """事件类型"""
    STRATEGY_START = "strategy_start"
    STRATEGY_STOP = "strategy_stop"
    ORDER_PLACED = "order_placed"
    ORDER_FILLED = "order_filled"
    ORDER_CANCELLED = "order_cancelled"
    POSITION_OPENED = "position_opened"
    POSITION_CLOSED = "position_closed"
    RISK_ALERT = "risk_alert"
    PERFORMANCE_METRIC = "performance_metric"
    ALERT_TRIGGERED = "alert_triggered"
    SYSTEM_ERROR = "system_error"


@dataclass
class CoreConfig:
    """核心配置"""
    # 日志配置
    log_level: str = "INFO"
    log_file: str = "logs/application.log"
    log_max_size: int = 10 * 1024 * 1024  # 10MB
    log_backup_count: int = 5
    structured_logging: bool = False
    json_format: bool = False
    
    # 数据配置
    data_dir: str = "data"
    cache_size: int = 1000
    
    # 性能配置
    max_workers: int = 4
    timeout: int = 30
    
    # 安全配置
    encryption_key_file: str = ".encryption_key"
    
    @classmethod
    def from_dict(cls, config_dict: Dict[str, Any]) -> 'CoreConfig':
        """从字典创建配置"""
        return cls(**{k: v for k, v in config_dict.items() if hasattr(cls, k)})
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'log_level': self.log_level,
            'log_file': self.log_file,
            'log_max_size': self.log_max_size,
            'log_backup_count': self.log_backup_count,
            'structured_logging': self.structured_logging,
            'json_format': self.json_format,
            'data_dir': self.data_dir,
            'cache_size': self.cache_size,
            'max_workers': self.max_workers,
            'timeout': self.timeout,
            'encryption_key_file': self.encryption_key_file
        }


class UnifiedLogger:
    """统一日志器"""
    
    _instance = None
    _loggers = {}
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def __init__(self):
        if hasattr(self, '_initialized'):
            return
        self._initialized = True
        self.config = None
        self._setup_done = False
    
    def setup(self, config: CoreConfig):
        """设置日志配置"""
        if self._setup_done:
            return
            
        self.config = config
        
        # 创建日志目录
        log_dir = Path(config.log_file).parent
        log_dir.mkdir(parents=True, exist_ok=True)
        
        # 设置根日志级别
        logging.getLogger().setLevel(getattr(logging, config.log_level))
        
        self._setup_done = True
    
    def get_logger(self, name: str) -> logging.Logger:
        """获取日志器"""
        if name in self._loggers:
            return self._loggers[name]
        
        logger = logging.getLogger(name)
        
        if not logger.handlers and self.config:
            # 文件处理器
            file_handler = logging.handlers.RotatingFileHandler(
                self.config.log_file,
                maxBytes=self.config.log_max_size,
                backupCount=self.config.log_backup_count,
                encoding='utf-8'
            )
            
            # 控制台处理器
            console_handler = logging.StreamHandler()
            
            # 格式化器
            if self.config.json_format:
                formatter = JsonFormatter()
            else:
                formatter = logging.Formatter(
                    '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
                )
            
            file_handler.setFormatter(formatter)
            console_handler.setFormatter(formatter)
            
            logger.addHandler(file_handler)
            logger.addHandler(console_handler)
            logger.setLevel(getattr(logging, self.config.log_level))
        
        self._loggers[name] = logger
        return logger
    
    def structured_log(self, logger_name: str, level: str, message: str, **kwargs):
        """结构化日志"""
        logger = self.get_logger(logger_name)
        log_data = {
            'message': message,
            'timestamp': datetime.now().isoformat(),
            **kwargs
        }
        
        if self.config and self.config.structured_logging:
            getattr(logger, level.lower())(json.dumps(log_data, ensure_ascii=False))
        else:
            getattr(logger, level.lower())(message)


class JsonFormatter(logging.Formatter):
    """JSON格式化器"""
    
    def format(self, record):
        log_data = {
            'timestamp': datetime.fromtimestamp(record.created).isoformat(),
            'level': record.levelname,
            'logger': record.name,
            'message': record.getMessage(),
            'module': record.module,
            'function': record.funcName,
            'line': record.lineno
        }
        
        if record.exc_info:
            log_data['exception'] = self.formatException(record.exc_info)
        
        return json.dumps(log_data, ensure_ascii=False)


class EventBus:
    """事件总线"""
    
    def __init__(self):
        self._listeners = defaultdict(list)
        self._logger = None
    
    def set_logger(self, logger):
        """设置日志器"""
        self._logger = logger
    
    def subscribe(self, event_type: EventTypes, callback: Callable):
        """订阅事件"""
        self._listeners[event_type].append(callback)
        if self._logger:
            self._logger.debug(f"订阅事件: {event_type.value}")
    
    def unsubscribe(self, event_type: EventTypes, callback: Callable):
        """取消订阅"""
        if callback in self._listeners[event_type]:
            self._listeners[event_type].remove(callback)
            if self._logger:
                self._logger.debug(f"取消订阅事件: {event_type.value}")
    
    async def emit(self, event_type: EventTypes, data: Dict[str, Any] = None):
        """发送事件"""
        if self._logger:
            self._logger.debug(f"发送事件: {event_type.value}, 数据: {data}")
        
        for callback in self._listeners[event_type]:
            try:
                if asyncio.iscoroutinefunction(callback):
                    await callback(data or {})
                else:
                    callback(data or {})
            except Exception as e:
                if self._logger:
                    self._logger.error(f"事件处理错误 {event_type.value}: {e}")
    
    def emit_sync(self, event_type: EventTypes, data: Dict[str, Any] = None):
        """同步发送事件"""
        if self._logger:
            self._logger.debug(f"同步发送事件: {event_type.value}, 数据: {data}")
        
        for callback in self._listeners[event_type]:
            try:
                if not asyncio.iscoroutinefunction(callback):
                    callback(data or {})
            except Exception as e:
                if self._logger:
                    self._logger.error(f"同步事件处理错误 {event_type.value}: {e}")


class ConfigManager:
    """配置管理器"""
    
    def __init__(self, config_file: str = "config.yaml"):
        self.config_file = config_file
        self._config = None
        self._logger = None
    
    def set_logger(self, logger):
        """设置日志器"""
        self._logger = logger
    
    def load_config(self) -> CoreConfig:
        """加载配置"""
        if self._config is not None:
            return self._config
        
        config_path = Path(self.config_file)
        
        if config_path.exists():
            try:
                with open(config_path, 'r', encoding='utf-8') as f:
                    if config_path.suffix.lower() == '.yaml':
                        config_data = yaml.safe_load(f) or {}
                    else:
                        config_data = json.load(f)
                
                self._config = CoreConfig.from_dict(config_data)
                if self._logger:
                    self._logger.info(f"配置加载成功: {config_path}")
                
            except Exception as e:
                if self._logger:
                    self._logger.error(f"配置加载失败: {e}")
                self._config = CoreConfig()
        else:
            self._config = CoreConfig()
            if self._logger:
                self._logger.info("使用默认配置")
        
        return self._config
    
    def save_config(self, config: CoreConfig):
        """保存配置"""
        try:
            config_path = Path(self.config_file)
            config_path.parent.mkdir(parents=True, exist_ok=True)
            
            with open(config_path, 'w', encoding='utf-8') as f:
                if config_path.suffix.lower() == '.yaml':
                    yaml.dump(config.to_dict(), f, default_flow_style=False, allow_unicode=True)
                else:
                    json.dump(config.to_dict(), f, indent=2, ensure_ascii=False)
            
            self._config = config
            if self._logger:
                self._logger.info(f"配置保存成功: {config_path}")
                
        except Exception as e:
            if self._logger:
                self._logger.error(f"配置保存失败: {e}")
            raise


class UnifiedCore:
    """统一核心管理器"""
    
    _instance = None
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def __init__(self):
        if hasattr(self, '_initialized'):
            return
        self._initialized = True
        
        # 初始化组件
        self.config_manager = ConfigManager()
        self.logger_manager = UnifiedLogger()
        self.event_bus = EventBus()
        
        # 加载配置
        self.config = self.config_manager.load_config()
        
        # 设置日志
        self.logger_manager.setup(self.config)
        self.logger = self.logger_manager.get_logger("unified_core")
        
        # 设置其他组件的日志器
        self.config_manager.set_logger(self.logger)
        self.event_bus.set_logger(self.logger)
        
        self.logger.info("统一核心初始化完成")
    
    def get_logger(self, name: str) -> logging.Logger:
        """获取日志器"""
        return self.logger_manager.get_logger(name)
    
    def get_config(self) -> CoreConfig:
        """获取配置"""
        return self.config
    
    def update_config(self, **kwargs):
        """更新配置"""
        config_dict = self.config.to_dict()
        config_dict.update(kwargs)
        new_config = CoreConfig.from_dict(config_dict)
        self.config_manager.save_config(new_config)
        self.config = new_config
        self.logger.info("配置已更新")
    
    def subscribe_event(self, event_type: EventTypes, callback: Callable):
        """订阅事件"""
        self.event_bus.subscribe(event_type, callback)
    
    def unsubscribe_event(self, event_type: EventTypes, callback: Callable):
        """取消订阅事件"""
        self.event_bus.unsubscribe(event_type, callback)
    
    async def emit_event(self, event_type: EventTypes, data: Dict[str, Any] = None):
        """发送事件"""
        await self.event_bus.emit(event_type, data)
    
    def emit_event_sync(self, event_type: EventTypes, data: Dict[str, Any] = None):
        """同步发送事件"""
        self.event_bus.emit_sync(event_type, data)


# 全局实例
unified_core = UnifiedCore()

# 便捷访问
unified_logger = unified_core.logger_manager
Logger = unified_core.logger_manager
event_bus = unified_core.event_bus
config_manager = unified_core.config_manager